package com.xgy.vue_role_system.controller;


import com.xgy.vue_role_system.config.redis.RedisService;
import com.xgy.vue_role_system.entity.Permission;
import com.xgy.vue_role_system.entity.User;
import com.xgy.vue_role_system.entity.UserInfo;
import com.xgy.vue_role_system.service.PermissionService;
import com.xgy.vue_role_system.utils.JwtUtils;
import com.xgy.vue_role_system.utils.MenuTree;
import com.xgy.vue_role_system.utils.Result;
import com.xgy.vue_role_system.vo.RouterVo;
import com.xgy.vue_role_system.vo.TokenVo;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/sysUser")
public class SysUserController {

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisService redisService;


    /**
     * 刷新token
     * @param request
     * @return
     */
    @PostMapping("/refreshToken")
    public Result refreshToken(HttpServletRequest request){
        //从Headers中获取token信息
        String token = request.getHeader("token");
        if(ObjectUtils.isEmpty(token)){
            //从请求参数中获取token
            token = request.getParameter("token");
        }
        //SpringSecurity上下文中获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //获取用户的身份信息
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        //定义变量，保存新的token
        String newToken = "";
        if(jwtUtils.validateToken(token,userDetails)){
            //重新生成新的token
            newToken = jwtUtils.refreshToken(token);
        }
        //获取本次token的到期时间
        long expireTime = Jwts.parser()
                .setSigningKey(jwtUtils.getSecret())
                .parseClaimsJws(newToken.replace("jwt_", ""))
                .getBody().getExpiration().getTime();
        //清除原来的token
        String oldTokenKey = "token_" + token;
        redisService.del(oldTokenKey);

        //将新的token信息保存到Redis中
        String newTokenKey = "token_" + newToken;
        redisService.set(newTokenKey,newToken,jwtUtils.getExpiration()/1000);

        //创建tokenVo对象
        TokenVo tokenVo = new TokenVo(expireTime, newToken);

        //返回数据给前端
        return Result.ok(tokenVo).message("token刷新成功！");
    }


    /**
     * 响应前端给登录用户指定信息
     * @return
     */
    @GetMapping("/getInfo")
    public Result getInfo(){
        //SpringSecurity上下文中获取用户信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        //判断身份信息authentication是否为空
        if(authentication == null){
            return Result.error().message("用户信息查询失败！");
        }
        //获取用户的身份信息
        User user = (User) authentication.getPrincipal();
        //获取该用户拥有的权限权限菜单列表
        List<Permission> permissionList = user.getPermissionList();

        //通过菜单列表获取对应的权限编码列表
        Object[] roles = permissionList.stream()
                .filter(Objects::nonNull)
                .map(Permission::getCode).filter(Objects::nonNull)
                .toArray();

        //封装用户信息
        UserInfo userInfo = new UserInfo(user.getId(), user.getNickName(), user.getAvatar(), null, roles);
        //返回数据给前端
        return Result.ok(userInfo).message("用户信息查询成功！");
    }


    /**
     * 响应给前端用户可用菜单对应的路由树
     *
     * @return
     */
    @GetMapping("/getRouterList")
    public Result getRouterList() {
        //从Spring Security上下文获取用户信息
        Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        //获取用户信息
        User user = (User) authentication.getPrincipal();
        //获取相应的权限
        List<Permission> permissionList = user.getPermissionList();
        //筛选目录和菜单
        List<Permission> collect = permissionList.stream()
                .filter(item -> item != null && item.getType() !=2) //0`目录，1`菜单，2`按钮，按钮不筛选
                .collect(Collectors.toList());
        //生成路由数据
        List<RouterVo> routerVoList = MenuTree.makeRouter(collect, 0L);
        //返回数据
        return Result.ok(routerVoList).message("路由树获取成功");
    }

    /**
     * 响应给前端用户可用的菜单树信息
     *
     * @return
     */
    @GetMapping("/getMenuList")
    public Result getMenuList() {
        //从Spring Security上下文获取用户信息
        Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        //获取用户信息
        User user = (User) authentication.getPrincipal();
        //获取相应的权限
        List<Permission> permissionList = user.getPermissionList();
        //筛选目录和菜单
        List<Permission> collect = permissionList.stream()
                .filter(item -> item != null && item.getType() !=2)
                .collect(Collectors.toList());
        //生成路由数据
        List<Permission> MenuList = MenuTree.makeMenuTree(collect, 0L);
        //返回数据
        return Result.ok(MenuList).message("菜单树获取成功");
    }

}